#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <stdint.h>
#include <errno.h>
#include <linux/fb.h>
#include <sys/mman.h>

#include<time.h>

#include "bmp.h"

#define DEBUG

#define WIDTH	320
#define HEIGHT	480

struct win_rect{
	unsigned short x;
	unsigned short y;
	unsigned short w;
	unsigned short h;
};

int rand_pic(void);
int draw_win(int fd, unsigned short *data, struct win_rect win);

int main(int argc, char *argv[])
{
    int fd, ret, num, cnt;
	Image	img;
	char fp[128];
	unsigned short *txbuf;

	struct win_rect win;
	
    if (argc < 2)
    {
        fprintf(stderr, "usage: ./app_ili9488 /dev/ili9488\n", argv[0]);
        exit(-1);
    }
	
	fd = open(argv[1], O_RDWR);
	if (fd < 0)
	{
		fprintf(stderr, "Can't open file %s: %s\n", argv[1], strerror(errno));
		close(fd);
		exit(-1);
	}

	win.x = 0;
	win.y = 0;
	win.w = WIDTH;
	win.h = HEIGHT;

	while(1)
	{
		num = rand_pic();
		sprintf(fp, "pic/%d.bmp", num);

		printf("file: %s\n", fp);

		ret = read_bmp_info(fp, &img);
		#ifdef DEBUG
		printf("info ret = %d, img.w = %d, img.h = %d\n", ret, img.width, img.height);
		#endif
		txbuf = (unsigned short*)malloc(img.width*img.height*2 + 8);
		
		ret = read_bmp_data(fp, (unsigned char*)txbuf, &img);
		if (ret == 0)
		{
			fprintf(stderr, "read picture fail!\n");
			goto out;
		}

		draw_win(fd, txbuf, win);
		usleep(100000);

		free(txbuf);
	}
	
out:
    close(fd);
	free(txbuf);
	
    return 0;
}

int rand_pic(void)
{
	int ret;
	srand((unsigned)time(NULL));
	ret = rand() % 10;
	//printf("rand = %d\n", ret);

	return ret;
}

int draw_win(int fd, unsigned short *data, struct win_rect win)
{
	int ret, i;
	
	data[0] = win.x;
	data[1] = win.y;
	data[2] = win.w;
	data[3] = win.h;
	
	// big-enddian - little-enddian
	for (i = 4; i < win.w*win.h; i++)
	{
		data[i] = (data[i] << 8) | (data[i] >> 8);
	}

	ret = write(fd, data, win.w * win.h * 2 + 8);

	return ret;
}

int read_bmp_info(char* name, Image *img)
{
	Rgbquad*				quad;
	Bitmapfileheader*		fileheader;
	Bitmapinfoheader*		infoheader;
	unsigned short			filetype;
	int 					num = 0;
	int 					fd;
	unsigned int			offset;
	
    fileheader = (Bitmapfileheader*)(malloc(sizeof(Bitmapfileheader)));
    memset(fileheader, 0, sizeof(Bitmapfileheader));
    infoheader = (Bitmapinfoheader*)(malloc(sizeof(Bitmapinfoheader)));
    memset(infoheader, 0, sizeof(Bitmapinfoheader));
    fd = open(name, O_RDONLY);
    if( fd < 0 )
    {
        perror("open()");
        goto out;
    }

    num = read(fd, &filetype, sizeof(unsigned short));
	if (num <= 0)
        goto out;

    if( filetype == 0x4D42 )
    {
        num = read(fd, fileheader, sizeof(Bitmapfileheader));
        if( num < 0 ) goto out;
		
		offset = fileheader->bfoffbits;
		num = read(fd, infoheader, sizeof(Bitmapinfoheader));
		if( num < 0) goto out;
		
		img->width = infoheader->bitwidth;
		img->height = infoheader->bitheight;
	}

out:
	free(infoheader);
	close(fd);
	return num;
}


int read_bmp_data(char* name, unsigned char* buff, Image *img)
{
    Rgbquad*                quad;
    Bitmapfileheader*       fileheader;
    Bitmapinfoheader*       infoheader;
    unsigned short          filetype;
    int                     num = 0;
    int                     fd;
    unsigned int            offset;

    fileheader = (Bitmapfileheader*)(malloc(sizeof(Bitmapfileheader)));
    memset(fileheader, 0, sizeof(Bitmapfileheader));
    infoheader = (Bitmapinfoheader*)(malloc(sizeof(Bitmapinfoheader)));
    memset(infoheader, 0, sizeof(Bitmapinfoheader));
    fd = open(name, O_RDONLY);
    if( fd < 0 )
    {
        perror("open()");
        goto out;
    }

    num = read(fd, &filetype, sizeof(unsigned short));
	if (num <= 0)
        goto out;

	#ifdef DEBUG
	printf("filetype =%#x\n",filetype);
	#endif

    if( filetype == 0x4D42 )
    {
        num = read(fd, fileheader, sizeof(Bitmapfileheader));
        if( num < 0 ) goto out;
		#ifdef DEBUG
        printf("fileheader->bfsize=%u\n",fileheader->bfsize);
        printf("fileheader->bfoffbits=%u\n",fileheader->bfoffbits);
		#endif
		
		offset = fileheader->bfoffbits;
		num = read(fd, infoheader, sizeof(Bitmapinfoheader));
		if( num < 0) goto out;
		#ifdef DEBUG
		printf("infoheader->bisize=%u\n", infoheader->bisize);
		#endif
		
		img->width = infoheader->bitwidth;
		img->height = infoheader->bitheight;
		#ifdef DEBUG
		printf("infoheader->bitwidth=%u\n",infoheader->bitwidth);
		printf("infoheader->bitheight=%u\n",infoheader->bitheight);
		printf("infoheader->biplanes=%u\n",infoheader->biplanes);
		printf("infoheader->bibitcount=%u\n",infoheader->bibitcount);
		printf("infoheader->bicompression=%u\n",infoheader->bicompression);
		printf("infoheader->biclrimportant=%#x\n",infoheader->biclrimportant);
		#endif
	}

	lseek(fd, offset+1, SEEK_SET );

	num = read(fd, buff + 8, (img->width)*(img->height)*2);
	#ifdef DEBUG
	printf("num=%d\n",num);
	#endif
	
	goto out;
out:
	free(fileheader);
	free(infoheader);
	close(fd);
	return num;
}


